# -*- coding: utf-8 -*-
"""
聚合数据API集成 - 机票和火车票数据获取
"""
import requests
import json
import time
from datetime import datetime, timedelta
from typing import List, Dict, Any, Optional

class JuheAPI:
    def __init__(self, flight_key: str, train_key: str):
        """
        初始化聚合数据API
        :param flight_key: 聚合数据机票API密钥
        :param train_key: 聚合数据火车票API密钥
        """
        self.flight_key = flight_key
        self.train_key = train_key
        self.base_url = "http://apis.juhe.cn"
        
        # 城市代码映射
        self.city_codes = {
            '北京': 'BJS', '上海': 'SHA', '广州': 'CAN', '深圳': 'SZX',
            '大连': 'DLC', '合肥': 'HFE', '南京': 'NKG', '杭州': 'HGH',
            '武汉': 'WUH', '成都': 'CTU', '重庆': 'CKG', '西安': 'SIA',
            '天津': 'TSN', '青岛': 'TAO', '沈阳': 'SHE', '哈尔滨': 'HRB',
            '长沙': 'CSX', '厦门': 'XMN', '福州': 'FOC', '济南': 'TNA',
            '郑州': 'CGO', '太原': 'TYN', '石家庄': 'SJW', '呼和浩特': 'HET'
        }
    
    def get_flight_data(self, origin: str, destination: str, date: str = None) -> List[Dict]:
        """
        获取机票数据
        :param origin: 出发城市
        :param destination: 到达城市
        :param date: 出发日期 (YYYY-MM-DD)
        :return: 航班数据列表
        """
        if not date:
            date = (datetime.now() + timedelta(days=1)).strftime('%Y-%m-%d')
        
        print(f"🔍 使用聚合数据API获取机票: {origin} → {destination} ({date})")
        
        try:
            # 聚合数据机票API
            url = f"{self.base_url}/flight/query"
            params = {
                'key': self.flight_key,
                'dtype': 'json',
                'from': self.city_codes.get(origin, origin),
                'to': self.city_codes.get(destination, destination),
                'date': date
            }
            
            response = requests.get(url, params=params, timeout=30)
            print(f"📊 API响应状态: {response.status_code}")
            
            if response.status_code == 200:
                data = response.json()
                print(f"📋 API响应: {json.dumps(data, ensure_ascii=False)[:200]}...")
                
                if data.get('error_code') == 0:
                    flights = self._parse_flight_data(data, origin, destination)
                    print(f"✅ 获取到 {len(flights)} 条机票数据")
                    return flights
                else:
                    print(f"❌ API错误: {data.get('reason', '未知错误')}")
                    return []
            else:
                print(f"❌ API请求失败: {response.status_code}")
                return []
                
        except Exception as e:
            print(f"❌ 机票API异常: {e}")
            return []
    
    def get_train_data(self, origin: str, destination: str, date: str = None) -> List[Dict]:
        """
        获取火车票数据
        :param origin: 出发城市
        :param destination: 到达城市
        :param date: 出发日期 (YYYY-MM-DD)
        :return: 火车票数据列表
        """
        if not date:
            date = (datetime.now() + timedelta(days=1)).strftime('%Y-%m-%d')
        
        print(f"🔍 使用聚合数据API获取火车票: {origin} → {destination} ({date})")
        
        try:
            # 聚合数据火车票API
            url = f"{self.base_url}/train/query"
            params = {
                'key': self.train_key,
                'dtype': 'json',
                'from': origin,
                'to': destination,
                'date': date
            }
            
            response = requests.get(url, params=params, timeout=30)
            print(f"📊 API响应状态: {response.status_code}")
            
            if response.status_code == 200:
                data = response.json()
                print(f"📋 API响应: {json.dumps(data, ensure_ascii=False)[:200]}...")
                
                if data.get('error_code') == 0:
                    trains = self._parse_train_data(data, origin, destination)
                    print(f"✅ 获取到 {len(trains)} 条火车票数据")
                    return trains
                else:
                    print(f"❌ API错误: {data.get('reason', '未知错误')}")
                    return []
            else:
                print(f"❌ API请求失败: {response.status_code}")
                return []
                
        except Exception as e:
            print(f"❌ 火车票API异常: {e}")
            return []
    
    def _parse_flight_data(self, data: Dict, origin: str, destination: str) -> List[Dict]:
        """解析机票数据"""
        flights = []
        
        try:
            result = data.get('result', {})
            flight_list = result.get('data', [])
            
            for item in flight_list:
                try:
                    flight = {
                        'type': 'flight',
                        'flight_number': item.get('flightNo', ''),
                        'airline': item.get('airlineName', ''),
                        'origin': origin,
                        'destination': destination,
                        'dep_time': item.get('departureTime', ''),
                        'arr_time': item.get('arrivalTime', ''),
                        'price': int(item.get('price', 0)),
                        'dep_airport': item.get('departureAirport', ''),
                        'arr_airport': item.get('arrivalAirport', ''),
                        'aircraft': item.get('aircraftType', ''),
                        'has_stop': '是' if item.get('stops', 0) > 0 else '否',
                        'is_transfer': '否',
                        'duration': item.get('duration', ''),
                        'source': '聚合数据API',
                        'crawl_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                    }
                    
                    if flight['price'] > 0:
                        flights.append(flight)
                        print(f"  ✅ 解析到航班: {flight['flight_number']} - ¥{flight['price']}")
                        
                except Exception as e:
                    print(f"  ❌ 解析航班条目异常: {e}")
                    continue
            
        except Exception as e:
            print(f"❌ 机票数据解析异常: {e}")
        
        return flights
    
    def _parse_train_data(self, data: Dict, origin: str, destination: str) -> List[Dict]:
        """解析火车票数据"""
        trains = []
        
        try:
            result = data.get('result', {})
            train_list = result.get('data', [])
            
            for item in train_list:
                try:
                    train = {
                        'type': 'train',
                        'train_number': item.get('trainNo', ''),
                        'train_type': item.get('trainType', ''),
                        'origin': origin,
                        'destination': destination,
                        'dep_time': item.get('departureTime', ''),
                        'arr_time': item.get('arrivalTime', ''),
                        'price': int(item.get('price', 0)),
                        'dep_station': item.get('departureStation', ''),
                        'arr_station': item.get('arrivalStation', ''),
                        'duration': item.get('duration', ''),
                        'seat_type': item.get('seatType', ''),
                        'is_high_speed': '是' if 'G' in item.get('trainNo', '') or 'D' in item.get('trainNo', '') else '否',
                        'source': '聚合数据API',
                        'crawl_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                    }
                    
                    if train['price'] > 0:
                        trains.append(train)
                        print(f"  ✅ 解析到火车: {train['train_number']} - ¥{train['price']}")
                        
                except Exception as e:
                    print(f"  ❌ 解析火车条目异常: {e}")
                    continue
            
        except Exception as e:
            print(f"❌ 火车票数据解析异常: {e}")
        
        return trains

class SmartSorter:
    """智能排序器"""
    
    @staticmethod
    def sort_by_price(data: List[Dict], reverse: bool = False) -> List[Dict]:
        """按价格排序"""
        return sorted(data, key=lambda x: x.get('price', 0), reverse=reverse)
    
    @staticmethod
    def sort_by_time(data: List[Dict], reverse: bool = False) -> List[Dict]:
        """按时间排序"""
        def time_key(item):
            dep_time = item.get('dep_time', '')
            # 提取时间部分进行排序
            if ' ' in dep_time:
                time_part = dep_time.split(' ')[-1]
            else:
                time_part = dep_time
            
            try:
                # 转换为时间对象进行排序
                if ':' in time_part:
                    hour, minute = map(int, time_part.split(':'))
                    return hour * 60 + minute
                return 0
            except:
                return 0
        
        return sorted(data, key=time_key, reverse=reverse)
    
    @staticmethod
    def sort_by_duration(data: List[Dict], reverse: bool = False) -> List[Dict]:
        """按行程时间排序"""
        def duration_key(item):
            duration = item.get('duration', '')
            try:
                # 提取小时和分钟
                if '小时' in duration and '分钟' in duration:
                    parts = duration.replace('小时', ' ').replace('分钟', '').split()
                    hours = int(parts[0]) if parts[0].isdigit() else 0
                    minutes = int(parts[1]) if len(parts) > 1 and parts[1].isdigit() else 0
                    return hours * 60 + minutes
                elif '小时' in duration:
                    hours = int(duration.replace('小时', ''))
                    return hours * 60
                elif '分钟' in duration:
                    minutes = int(duration.replace('分钟', ''))
                    return minutes
                return 0
            except:
                return 0
        
        return sorted(data, key=duration_key, reverse=reverse)
    
    @staticmethod
    def sort_by_comfort(data: List[Dict]) -> List[Dict]:
        """按舒适度排序（高铁 > 飞机 > 普通火车）"""
        def comfort_key(item):
            if item.get('type') == 'flight':
                return 3  # 飞机最舒适
            elif item.get('type') == 'train':
                if item.get('is_high_speed') == '是':
                    return 2  # 高铁次之
                else:
                    return 1  # 普通火车
            return 0
        
        return sorted(data, key=comfort_key, reverse=True)
    
    @staticmethod
    def smart_sort(data: List[Dict], sort_type: str = 'smart') -> List[Dict]:
        """智能排序"""
        if not data:
            return data
        
        if sort_type == 'price_low':
            return SmartSorter.sort_by_price(data, reverse=False)
        elif sort_type == 'price_high':
            return SmartSorter.sort_by_price(data, reverse=True)
        elif sort_type == 'time_early':
            return SmartSorter.sort_by_time(data, reverse=False)
        elif sort_type == 'time_late':
            return SmartSorter.sort_by_time(data, reverse=True)
        elif sort_type == 'duration_short':
            return SmartSorter.sort_by_duration(data, reverse=False)
        elif sort_type == 'duration_long':
            return SmartSorter.sort_by_duration(data, reverse=True)
        elif sort_type == 'comfort':
            return SmartSorter.sort_by_comfort(data)
        else:  # smart排序
            # 综合排序：价格权重40%，时间权重30%，舒适度权重30%
            def smart_key(item):
                price = item.get('price', 0)
                time_score = SmartSorter._get_time_score(item)
                comfort_score = SmartSorter._get_comfort_score(item)
                
                # 归一化分数
                price_score = max(0, 100 - price / 10)  # 价格越低分数越高
                
                return price_score * 0.4 + time_score * 0.3 + comfort_score * 0.3
            
            return sorted(data, key=smart_key, reverse=True)
    
    @staticmethod
    def _get_time_score(item):
        """获取时间分数"""
        dep_time = item.get('dep_time', '')
        try:
            if ' ' in dep_time:
                time_part = dep_time.split(' ')[-1]
            else:
                time_part = dep_time
            
            if ':' in time_part:
                hour, minute = map(int, time_part.split(':'))
                # 早上6点到晚上10点分数更高
                if 6 <= hour <= 22:
                    return 80
                else:
                    return 40
            return 50
        except:
            return 50
    
    @staticmethod
    def _get_comfort_score(item):
        """获取舒适度分数"""
        if item.get('type') == 'flight':
            return 90
        elif item.get('type') == 'train':
            if item.get('is_high_speed') == '是':
                return 80
            else:
                return 60
        return 50

def test_juhe_api():
    """测试聚合数据API"""
    print("🧪 测试聚合数据API")
    print("=" * 60)
    
    # 这里需要您提供真实的API密钥
    flight_key = "YOUR_FLIGHT_API_KEY"  # 请替换为真实的API密钥
    train_key = "YOUR_TRAIN_API_KEY"    # 请替换为真实的API密钥
    
    if flight_key == "YOUR_FLIGHT_API_KEY":
        print("⚠️  请先设置真实的API密钥")
        print("1. 访问 https://www.juhe.cn/ 注册账号")
        print("2. 申请机票和火车票API")
        print("3. 将API密钥替换到代码中")
        return
    
    # 创建API实例
    api = JuheAPI(flight_key, train_key)
    
    # 测试机票API
    print("\n🔍 测试机票API...")
    flights = api.get_flight_data("大连", "北京", "2025-09-19")
    
    # 测试火车票API
    print("\n🔍 测试火车票API...")
    trains = api.get_train_data("大连", "北京", "2025-09-19")
    
    # 合并数据
    all_data = flights + trains
    
    # 测试智能排序
    print("\n🧠 测试智能排序...")
    sorter = SmartSorter()
    
    # 按价格排序
    price_sorted = sorter.sort_by_price(all_data, reverse=False)
    print(f"📊 按价格排序: {len(price_sorted)} 条数据")
    
    # 按时间排序
    time_sorted = sorter.sort_by_time(all_data, reverse=False)
    print(f"📊 按时间排序: {len(time_sorted)} 条数据")
    
    # 智能排序
    smart_sorted = sorter.smart_sort(all_data, 'smart')
    print(f"📊 智能排序: {len(smart_sorted)} 条数据")
    
    # 显示前5条数据
    print("\n📋 前5条数据:")
    for i, item in enumerate(smart_sorted[:5], 1):
        item_type = "✈️ 航班" if item.get('type') == 'flight' else "🚄 火车"
        print(f"{i}. {item_type} {item.get('flight_number', item.get('train_number', ''))} - ¥{item.get('price', 0)}")

if __name__ == "__main__":
    test_juhe_api()